<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>VueUse | 陈梁月</title>
    <meta name="generator" content="VuePress 1.6.0">
    
    <meta name="description" content="
双token，refreshToken和token，正常请求用token，如果token过期，用refreshToken去请求新的token，如果refreshToken也过期，则退出登录
登陆获取两个token 存储到pinia（这边用了pinia持久化工具，保存到sessionStorage里）
   `javascript
   // pinia 数据持久化 ...">
    <link rel="preload" href="/jiraiya-chen-blog/assets/css/0.styles.a76d507b.css" as="style"><link rel="preload" href="/jiraiya-chen-blog/assets/js/app.61a538cd.js" as="script"><link rel="preload" href="/jiraiya-chen-blog/assets/js/6.cdd050e5.js" as="script"><link rel="preload" href="/jiraiya-chen-blog/assets/js/3.c32d983c.js" as="script"><link rel="preload" href="/jiraiya-chen-blog/assets/js/24.cc206537.js" as="script"><link rel="prefetch" href="/jiraiya-chen-blog/assets/js/10.69f07e0e.js"><link rel="prefetch" href="/jiraiya-chen-blog/assets/js/11.53f87820.js"><link rel="prefetch" href="/jiraiya-chen-blog/assets/js/12.ae4be476.js"><link rel="prefetch" href="/jiraiya-chen-blog/assets/js/13.3c5cc435.js"><link rel="prefetch" href="/jiraiya-chen-blog/assets/js/14.7fe16526.js"><link rel="prefetch" href="/jiraiya-chen-blog/assets/js/15.35217ffc.js"><link rel="prefetch" href="/jiraiya-chen-blog/assets/js/16.a0eac610.js"><link rel="prefetch" href="/jiraiya-chen-blog/assets/js/17.82bb9b86.js"><link rel="prefetch" href="/jiraiya-chen-blog/assets/js/18.217868a1.js"><link rel="prefetch" href="/jiraiya-chen-blog/assets/js/19.9bd59858.js"><link rel="prefetch" href="/jiraiya-chen-blog/assets/js/20.654ddc5a.js"><link rel="prefetch" href="/jiraiya-chen-blog/assets/js/21.ca86705f.js"><link rel="prefetch" href="/jiraiya-chen-blog/assets/js/22.82e1511c.js"><link rel="prefetch" href="/jiraiya-chen-blog/assets/js/23.460b2cad.js"><link rel="prefetch" href="/jiraiya-chen-blog/assets/js/4.00b7630e.js"><link rel="prefetch" href="/jiraiya-chen-blog/assets/js/5.631f1efc.js"><link rel="prefetch" href="/jiraiya-chen-blog/assets/js/7.7b6ab354.js"><link rel="prefetch" href="/jiraiya-chen-blog/assets/js/8.0b74c858.js"><link rel="prefetch" href="/jiraiya-chen-blog/assets/js/9.ce3d6c06.js"><link rel="prefetch" href="/jiraiya-chen-blog/assets/js/vuejs-paginate.c82c253b.js">
    <link rel="stylesheet" href="/jiraiya-chen-blog/assets/css/0.styles.a76d507b.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div id="vuepress-theme-blog__global-layout"><section id="header-wrapper"><header id="header"><div class="header-wrapper"><div class="title"><a href="/jiraiya-chen-blog/" class="nav-link home-link">陈梁月 </a></div> <div class="header-right-wrap"><ul class="nav"><li class="nav-item"><a href="/jiraiya-chen-blog/" class="nav-link">博文</a></li><li class="nav-item"><a href="/jiraiya-chen-blog/tag/" class="nav-link">标签</a></li></ul> <div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <!----></div></div></header></section> <div id="mobile-header"><div class="mobile-header-bar"><div class="mobile-header-title"><a href="/jiraiya-chen-blog/" class="nav-link mobile-home-link">陈梁月 </a> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu"><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line></svg></div> <div class="mobile-menu-wrapper"><hr class="menu-divider"> <ul class="mobile-nav"><li class="mobile-nav-item"><a href="/jiraiya-chen-blog/" class="nav-link">博文</a></li><li class="mobile-nav-item"><a href="/jiraiya-chen-blog/tag/" class="nav-link">标签</a></li> <li class="mobile-nav-item"><!----></li></ul></div></div></div> <div class="content-wrapper"><div id="vuepress-theme-blog__post-layout"><article itemscope="itemscope" itemtype="https://schema.org/BlogPosting" class="vuepress-blog-theme-content"><header><h1 itemprop="name headline" class="post-title">
        VueUse
      </h1> <div class="post-meta"><div itemprop="publisher author" itemtype="http://schema.org/Person" itemscope="itemscope" class="post-meta-author"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-navigation"><polygon points="3 11 22 2 13 21 11 13 3 11"></polygon></svg> <span itemprop="name">Jiraiya</span> <span itemprop="address">   in 苏州</span></div> <div class="post-meta-date"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clock"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg> <time pubdate itemprop="datePublished" datetime="2023-09-26T00:00:00.000Z">
      2023-09-26
    </time></div> <ul itemprop="keywords" class="post-meta-tags"><li class="post-tag" data-v-42ccfcd5><a href="/jiraiya-chen-blog/tag/Vue" data-v-42ccfcd5><span data-v-42ccfcd5>Vue</span></a></li><li class="post-tag" data-v-42ccfcd5><a href="/jiraiya-chen-blog/tag/Axois" data-v-42ccfcd5><span data-v-42ccfcd5>Axois</span></a></li></ul></div></header> <div itemprop="articleBody" class="content__default"><h4 id="思路"><a href="#思路" class="header-anchor">#</a> 思路</h4> <p>双token，refreshToken和token，正常请求用token，如果token过期，用refreshToken去请求新的token，如果refreshToken也过期，则退出登录</p> <ol><li><p>登陆获取两个token 存储到pinia（这边用了pinia持久化工具，保存到sessionStorage里）</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token comment">// pinia 数据持久化    </span>
<span class="token function">setOwnToken</span><span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
   <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">$patch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">state</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      state<span class="token punctuation">.</span>token <span class="token operator">=</span> data<span class="token punctuation">.</span>token
      state<span class="token punctuation">.</span>refreshToken <span class="token operator">=</span> data<span class="token punctuation">.</span>refreshToken
   <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
</code></pre></div><div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">let</span> <span class="token punctuation">{</span>data<span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">loginReq</span><span class="token punctuation">(</span>encryptData<span class="token punctuation">)</span>
<span class="token function">setOwnToken</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span>
</code></pre></div></li> <li><p>axios实例 请求后拦截</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code>
<span class="token keyword">let</span> requests <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token comment">// 错误接口队列</span>
<span class="token comment">// 只执行一次的flag 如果有多个异步请求同时发起，此时token又过期了，</span>
<span class="token keyword">let</span> isRefreshing <span class="token operator">=</span> <span class="token boolean">false</span> 

service<span class="token punctuation">.</span>interceptors<span class="token punctuation">.</span>response<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span>
  <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token comment">// 这边 的两个token 我存到了pinia里</span>
    <span class="token keyword">const</span> <span class="token punctuation">{</span> refreshToken<span class="token punctuation">,</span> token <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">storeToRefs</span><span class="token punctuation">(</span><span class="token function">useBasicStore</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token comment">// eslint-disable-next-line camelcase</span>
    <span class="token comment">// 这边的返回结果和后端商量好</span>
    <span class="token keyword">const</span> <span class="token punctuation">{</span> flag<span class="token punctuation">,</span> content<span class="token punctuation">,</span> next_operation <span class="token punctuation">}</span> <span class="token operator">=</span> res<span class="token punctuation">.</span>data<span class="token punctuation">.</span>message
    <span class="token comment">// 正常返回值</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>flag <span class="token operator">===</span> <span class="token string">'success'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">return</span> res<span class="token punctuation">.</span>data
      <span class="token comment">// 错误返回值</span>
      <span class="token comment">// 情况一：退出登陆</span>
      <span class="token comment">// 情况二：获取新token</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>flag <span class="token operator">===</span> <span class="token string">'error'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token comment">// 如果是退出 并且没token 重新登陆</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span>next_operation <span class="token operator">===</span> <span class="token string">'exit'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// todo 退出，无token  重新登陆</span>
      <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>isRefreshing<span class="token punctuation">)</span> <span class="token punctuation">{</span>
          isRefreshing <span class="token operator">=</span> <span class="token boolean">true</span>
            <span class="token comment">// 返回的是一个异步函数</span>
            <span class="token comment">// 页面接口请求，发现token过期了，返回一个异步函数，执行完成后，重新发起原本的错误请求</span>
          <span class="token keyword">return</span> <span class="token function">userRefreshTokenCheck</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resp</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
              refreshToken<span class="token punctuation">.</span>value <span class="token operator">=</span> resp<span class="token punctuation">.</span>refreshToken
              token<span class="token punctuation">.</span>value <span class="token operator">=</span> resp<span class="token punctuation">.</span>token
              <span class="token comment">// token 刷新后将数组的方法重新执行</span>
              requests<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">cb</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token function">cb</span><span class="token punctuation">(</span>token<span class="token punctuation">)</span><span class="token punctuation">)</span>
              requests <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token comment">// 重新请求完清空</span>
              <span class="token keyword">return</span> <span class="token function">service</span><span class="token punctuation">(</span>res<span class="token punctuation">.</span>config<span class="token punctuation">)</span>
            <span class="token punctuation">}</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
              <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span>
            <span class="token punctuation">}</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">finally</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
              isRefreshing <span class="token operator">=</span> <span class="token boolean">false</span>
            <span class="token punctuation">}</span><span class="token punctuation">)</span>
        <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
          <span class="token comment">// 返回未执行 resolve 的 Promise</span>
          <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
            <span class="token comment">// 用函数形式将 resolve 存入，等待刷新后再执行</span>
            requests<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">token</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
              res<span class="token punctuation">.</span>headers<span class="token punctuation">.</span>Authorization <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>token<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span>
              res<span class="token punctuation">.</span>config<span class="token punctuation">.</span>data <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>res<span class="token punctuation">.</span>config<span class="token punctuation">.</span>data<span class="token punctuation">)</span>
              <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token function">service</span><span class="token punctuation">(</span>res<span class="token punctuation">.</span>config<span class="token punctuation">)</span><span class="token punctuation">)</span>
            <span class="token punctuation">}</span><span class="token punctuation">)</span>
          <span class="token punctuation">}</span><span class="token punctuation">)</span>
        <span class="token punctuation">}</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token comment">//响应报错</span>
  <span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> Promise<span class="token punctuation">.</span><span class="token function">reject</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">)</span>
</code></pre></div></li></ol></div> <footer><!----> <hr> <!----></footer></article> <!----></div></div> <footer class="footer" data-v-fdbf4940><div class="footer-left-wrap" data-v-fdbf4940><ul class="contact" data-v-fdbf4940></ul></div> <div class="footer-right-wrap" data-v-fdbf4940><ul class="copyright" data-v-fdbf4940><li class="copyright-item" data-v-fdbf4940><a href="/jiraiya-chen-blog/2023/09/26/%E6%97%A0%E6%84%9F%E5%88%B7%E6%96%B0/.html" class="nav-link" data-v-fdbf4940>Jiraiya Chen © 2023</a></li></ul></div></footer></div><div class="global-ui"></div></div>
    <script src="/jiraiya-chen-blog/assets/js/app.61a538cd.js" defer></script><script src="/jiraiya-chen-blog/assets/js/6.cdd050e5.js" defer></script><script src="/jiraiya-chen-blog/assets/js/3.c32d983c.js" defer></script><script src="/jiraiya-chen-blog/assets/js/24.cc206537.js" defer></script>
  </body>
</html>
